package com.adkun.community.controller;

import com.adkun.community.annotation.LoginRequired;
import com.adkun.community.entity.Comment;
import com.adkun.community.entity.DiscussPost;
import com.adkun.community.entity.Page;
import com.adkun.community.entity.User;
import com.adkun.community.service.*;
import com.adkun.community.util.CommunityUtil;
import com.adkun.community.util.HostHolder;
import com.alibaba.fastjson.JSONObject;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.context.Context;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import static com.adkun.community.util.CommunityConstants.ENTITY_TYPE_POST;
import static com.adkun.community.util.CommunityConstants.ENTITY_TYPE_USER;

@Controller
@RequestMapping("/user")
public class UserController {

    @Value("${community.path.upload}")
    private String uploadPath;

    @Value("${community.path.domain}")
    private String domainPath;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Autowired
    private UserService userService;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private LikeService likeService;

    @Value("${qiniu.key.access}")
    private String accessKey;

    @Value("${qiniu.key.secret}")
    private String secretKey;

    @Value("${qiniu.bucket.header.name}")
    private String headerBucketName;

    @Value("${qiniu.bucket.header.url}")
    private String headerBucketUrl;

    /**
     * 更新头像地址
     *
     * @param fileName
     * @return
     */
    @PostMapping("/header/url")
    @ResponseBody
    public String updateHeaderUrl(String fileName) {
        if (StringUtils.isBlank(fileName)) {
            return CommunityUtil.getJSONString(1, "文件名不能为空！");
        }

        String url = "http://" + headerBucketUrl + "/" + fileName;
        userService.updateHeader(hostHolder.getUser().getId(), url);

        return CommunityUtil.getJSONString(0);
    }

    /**
     * 设置页面
     * 生成七牛云Token
     *
     * @return
     */
    @GetMapping("/setting")
    public String getSettingPage(Model model) {
        String fileName = CommunityUtil.generateUUID();
        // 设置响应信息
        StringMap policy = new StringMap();
        // 希望返回一个JSON字符串，而不是同步请求默认的HTML
        policy.put("returnBody", CommunityUtil.getJSONString(0));
        // 生成上传凭证
        Auth auth = Auth.create(accessKey, secretKey);
        String uploadToken = auth.uploadToken(headerBucketName, fileName, 3600, policy);

        model.addAttribute("uploadToken", uploadToken);
        model.addAttribute("fileName", fileName);

        return "site/setting";
    }

    @RequestMapping(path = "/setting", method = RequestMethod.POST)
    public String setting(String oldPassword, String newPassword, Model model) {
        User u = hostHolder.getUser();
        Map<String, Object> map = userService.updatePassword(u.getId(), oldPassword, newPassword);

        if (map == null) {
            return "redirect:/logout";
        } else {
            model.addAttribute("oldPasswordMsg", map.get("oldPasswordMsg"));
            model.addAttribute("newPasswordMsg", map.get("newPasswordMsg"));
//            model.addAttribute("confirmPsswordMsg", map.get("confirmPasswordMsg"));
            return "/site/setting";
        }
    }

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);


    /**
     * 废弃的上传头像
     *
     * @param headerImage
     * @param model
     * @return
     * @throws IOException
     */
    @Deprecated
    @RequestMapping(path = "upload", method = RequestMethod.POST)
    public String uploadHeader(MultipartFile headerImage, Model model) throws IOException {
        if (headerImage == null) {
            model.addAttribute("error", "您还没有选择图片！");
            return "/site/setting";
        }
        
        /*
        文件要重命名，因为很多人上传的都是1.png这种名字，就会覆盖掉
        注意后缀不能覆盖掉（截取）
         */
        String fileName = headerImage.getOriginalFilename();
        String surfix = fileName.substring(fileName.lastIndexOf(".")); // 从最后一个点的索引往后截取
        if (StringUtils.isBlank(surfix)) {
            model.addAttribute("error", "文件格式不正确！");
            return "/site/setting";
        }

        // 生成随机文件名
        String newFileName = CommunityUtil.generateUUID() + surfix;
        // 确定文件存放路径
        File dest = new File(uploadPath + "/" + newFileName);
        CommunityUtil.createFile(dest);
        try {
            headerImage.transferTo(dest);
        } catch (IOException e) {
            logger.error("文件上传失败！" + e.getMessage());
            throw new RuntimeException("上传文件失败，服务器发生异常！");
        }

        // 更新当前用户的头像路径（web访问路径）
        // http://localhost:8081/community/user/header/xxx.png
        User u = hostHolder.getUser();
        String headerUrl = domainPath + contextPath + "/user/header/" + newFileName;
        userService.updateHeader(u.getId(), headerUrl);
        return "redirect:/index";
    }

    /**
     * 废弃的获取头像
     */
    @Deprecated
    @RequestMapping(path = "/header/{fileName}", method = RequestMethod.GET)
    public void getHeader(@PathVariable("fileName") String fileName, HttpServletResponse response) {
        // 服务器存放路径 uploadPath + "/" + fileName
        fileName = uploadPath + "/" + fileName;
        // 文件后缀;
        String surfix = fileName.substring(fileName.lastIndexOf("."));
        // 响应图片
        response.setContentType("image/" + surfix);
        try (
                FileInputStream fis = new FileInputStream(fileName); // 输入流需要手动关闭，用该语法可以自动关闭，也可以写到finally
        ) {
            OutputStream os = response.getOutputStream();

            byte[] buffer = new byte[1024]; // 输出缓冲区，1024字节输出
            int b = 0;
            while ((b = fis.read(buffer)) != -1) {
                // 每次read buffer大小的数据
                // -1就是没读成功
                os.write(buffer, 0, b);
            }
        } catch (IOException e) {
            logger.error("读取图像失败！" + e.getMessage());
        }
    }

    @Autowired
    private FollowService followService;

    // 个人主页
    @RequestMapping(path = "/profile/{userId}", method = RequestMethod.GET)
    public String getProfilePage(@PathVariable("userId") int userId, Model model) {
        User user = userService.findUserById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在！");
        }

        //用户
        model.addAttribute("user", user);
        // 点赞数量
        int likeCount = likeService.findUserLikeCount(userId);
        model.addAttribute("likeCount", likeCount);

        // 关注数量
        long followeeCount = followService.findFolloweeCount(userId, ENTITY_TYPE_USER);
        model.addAttribute("followeeCount", followeeCount);
        // 粉丝数量
        long followerCount = followService.findFollowerCount(ENTITY_TYPE_USER, userId);
        model.addAttribute("followerCount", followerCount);
        // 是否已关注 
        boolean hasFollowed = false;
        if (hostHolder.getUser() != null) {
            hasFollowed = followService.hasFollowed(hostHolder.getUser().getId(), ENTITY_TYPE_USER, userId);
        }

        model.addAttribute("hasFollowed", hasFollowed);

        return "/site/profile";
    }


    @Autowired
    private DiscussPostService postService;


    /**
     * 获取我的帖子列表，支持分页
     * 获取帖子点赞数量
     *
     * @param model
     * @return
     */
    @LoginRequired
    @RequestMapping(path = "/mypost", method = RequestMethod.GET)
    public String getMyPost(Model model, Page page) {
        // 获取当前用户
        User user = hostHolder.getUser();

        if (user == null) {
            return "redirect:/index";
        }
        // 获取分页
//        Page page = new Page();
        page.setPath("/user/mypost");
        page.setLimit(5);
        page.setRows(postService.findDiscussPostsCount(user.getId()));
        // 获取当前用户发的帖子列表
        List<DiscussPost> posts = postService.findDiscussPosts(user.getId(), page.getOffset(), page.getLimit(), 0);

        List<Map<String, Object>> postsVo = new ArrayList<>();
        for (DiscussPost post : posts) {
            //
            Map<String, Object> map = new HashMap<>();
            map.put("post", post);
            // 获取这个post的点赞数量
            long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, post.getId());
            map.put("likeCount", likeCount);

            postsVo.add(map);
        }

        model.addAttribute("posts", postsVo);
        model.addAttribute("page", page);

        return "/site/my-post";
    }

    @Autowired
    private CommentService commentService;

    @LoginRequired
    @RequestMapping(path = "/myreply", method = RequestMethod.GET)
    public String getMyReply(Model model, Page page) {
        User user = hostHolder.getUser();

        if (user == null) {
            return "redirect:/index";
        }
        // 设置分页
        // 当前用户的评论数量
        int commentsCount = commentService.findUserComentCount(user.getId());
        page.setRows(commentsCount);
        page.setLimit(5);
        page.setPath("/user/myreply");

        List<Comment> comments = commentService.findUserComments(user.getId(), page.getOffset(), page.getLimit());

        List<Map<String, Object>> commentsVo = new ArrayList<>();

        for (Comment comment : comments) {
            Map<String, Object> map = new HashMap<>();
            map.put("comment", comment);

            // 找到对应的帖子
            DiscussPost discussPost = postService.findDiscussPostById(comment.getEntityId());
            map.put("target", discussPost);

            commentsVo.add(map);
        }
        model.addAttribute("comments", commentsVo);
        model.addAttribute("commentsCount", commentsCount);

        return "/site/my-reply";
    }

    /**
     * 忘记密码
     *
     * @return
     */
    @RequestMapping(path = "/forget", method = RequestMethod.GET)
    public String getForgetPage() {
        return "/site/forget";
    }

    @RequestMapping(path = "/forget", method = RequestMethod.POST)
    public String forget(Model model, String email, String kaptcha, String newPassword) {
        Map<String, Object> msgs = userService.forget(email, newPassword, kaptcha);
        if (msgs != null && !msgs.isEmpty()) {
            if (msgs.containsKey("emailMsg")) {
                model.addAttribute("emailMsg", msgs.get("emailMsg"));
            }
            if (msgs.containsKey("kaptchaMsg")) {
                model.addAttribute("kaptchaMsg", msgs.get("kaptchaMsg"));
            }
            if (msgs.containsKey("newPasswordMsg")) {
                model.addAttribute("newPasswordMsg", msgs.get("newPasswordMsg"));
            }
        }
        model.addAttribute("email", email);
        return "/site/forget";
    }

    /**
     * 发送忘记密码的验证码
     *
     * @param model
     * @param email
     * @return
     */
    @RequestMapping(path = "/sendcode", method = RequestMethod.POST)
    @ResponseBody
    public String sendCode(Model model, String email) {
        Map<String, Object> msgs = userService.sendCode(email);
        JSONObject json = new JSONObject();
        if (msgs != null && !msgs.isEmpty()) {
            if (msgs.containsKey("emailMsg")) {
                json.put("emailMsg", msgs.get("emailMsg"));
                json.put("code", 1);
            }
            if (msgs.containsKey("kaptchaMsg")) {
                json.put("kaptchaMsg", msgs.get("kaptchaMsg"));
                json.put("code", 1);
            }
        } else {
            json.put("code", 0);
        }

        return json.toString();
    }
}
